package com.gitee.dolt.boot.request;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.gitee.dolt.core.base.entity.Entity;
import com.gitee.dolt.core.base.entity.SuperEntity;
import com.gitee.dolt.core.util.AntiSqlFilter;
import com.gitee.dolt.database.util.MybatisUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * @author LYH
 */
@Data
@ApiModel(value = "QueryParams", description = "查询参数")
public class QueryParams<T> {
    @NotNull(message = "查询对象model不能为空")
    @ApiModelProperty(value = "查询参数", required = true)
    protected T model;

    @ApiModelProperty(value = "排序,createdTime", allowableValues = "id,uuid,createTime,updateTime", example = "id")
    protected String sort;

    @ApiModelProperty(value = "排序规则, 默认descending", allowableValues = "descending,ascending", example = "descending")
    protected String order = "descending";

    @ApiModelProperty(value = "关键字")
    protected String keyword;

    @ApiModelProperty(value = "扩展参数")
    protected Map<String, String> map = new HashMap<>(1);

    /**
     * 支持多个字段排序，用法：
     * eg.1, 参数：{order:"name,id", order:"descending,ascending" }。 排序： name desc, id asc
     * eg.2, 参数：{order:"name", order:"descending,ascending" }。 排序： name desc
     * eg.3, 参数：{order:"name,id", order:"descending" }。 排序： name desc
     *
     * @return
     */
    @JsonIgnore
    public List<OrderItem> getOrders() {
        List<OrderItem> orders = new ArrayList<>();
        String[] sortArr = StrUtil.split(this.getSort(), StrUtil.COMMA);
        String[] orderArr = StrUtil.split(this.getOrder(), StrUtil.COMMA);

        int len = sortArr.length < orderArr.length ? sortArr.length : orderArr.length;
        for (int i = 0; i < len; i++) {
            String humpSort = sortArr[i];
            // 简单的 驼峰 转 下划线
//            String underlineSort = StrUtil.toUnderlineCase(humpSort);
            String underlineSort = humpSort;

            // 除了 create_time 和 updateTime 都过滤sql关键字
            if (!StrUtil.equalsAny(humpSort, SuperEntity.CREATE_TIME, Entity.UPDATE_TIME)) {
                underlineSort = AntiSqlFilter.getSafeValue(underlineSort);
            }

            orders.add("ascending".equals(orderArr[i]) ? OrderItem.asc(underlineSort) : OrderItem.desc(underlineSort));
        }
        return orders;
    }


    /**
     * 处理时间区间，可以覆盖后处理组装查询条件
     *
     * @param queryWrapper
     */
    public <Entity> QueryWrapper<Entity> handlerWrapper(QueryWrapper<Entity> queryWrapper) {
        Class<?> entityClass = Optional.ofNullable(queryWrapper.getEntity()).map(e -> e.getClass()).orElse(null);
        if (CollUtil.isNotEmpty(this.map)) {
            //拼装区间
            for (Map.Entry<String, String> field : this.map.entrySet()) {
                String key = field.getKey();
                String value = field.getValue();
                if (StrUtil.isEmpty(value)) {
                    continue;
                }
                if (key.endsWith("_st")) {
                    String beanField = StrUtil.subBefore(key, "_st", true);
                    queryWrapper.ge(entityClass == null ? beanField : MybatisUtils.getDbField(beanField, entityClass), DateUtil.parseDate(value));
                }
                if (key.endsWith("_ed")) {
                    String beanField = StrUtil.subBefore(key, "_ed", true);
                    queryWrapper.le(entityClass == null ? beanField : MybatisUtils.getDbField(beanField, entityClass), DateUtil.parseDate(value));
                }
            }
        }
        return queryWrapper;
    }
}
